package yartiss.engine.simulation.scheduling.policies.dp;

import java.util.ArrayList;
import java.util.List;
import java.util.SortedSet;

import yartiss.engine.simulation.IEnergyProfile;
import yartiss.engine.simulation.ISchedulingPolicy;
import yartiss.engine.simulation.Processor;
import yartiss.engine.simulation.events.EventGenerator;
import yartiss.engine.simulation.partition.DynamicPartitionManager;
import yartiss.engine.simulation.scheduling.policies.AbstractMultiProcSchedulingPolicy;
import yartiss.engine.simulation.system.ITask;
import yartiss.engine.simulation.system.ITaskSet;
import yartiss.engine.simulation.system.taskset.TaskSetFactory;

public class LaxityGraphMultiProcSchedulingPolicy extends
		AbstractMultiProcSchedulingPolicy {

	@Override
	public String getPolicyName() {
		return "Laxity_graph";
	}

	@Override
	public ITaskSet createTaskSet() {
		return TaskSetFactory.getNewInstance("laxity");
	}
	
	@Override
	public ISchedulingPolicy newInstance(){
		return new LaxityGraphMultiProcSchedulingPolicy();
	}

	@Override
	public Processor[] chooseNextTasks(Processor[] processors,
			ITaskSet taskSet, IEnergyProfile energyProfile, long date,
			EventGenerator evGen) {
		SortedSet<ITask> activeTasks = taskSet.getActiveTasks(date);
		List<ITask> partitionTasks = new ArrayList<ITask>();

		// int i=0;
		for (ITask task : activeTasks) {
			// if(i<processors.length){

			long hlcet = energyProfile.howLongCanExecute(task);
			if (hlcet <= 0) {
				evGen.generateEvent("energy_failure", task, date, null);
				// processors[i].setNextTask(null);
			} else {
				if (hlcet < task.getRemainingCost())
					evGen.generateEvent("check_energy_state", task, date
							+ hlcet, null);
				// processors[i].setNextTask(task);
				partitionTasks.add(task);
			}
			// }
			// i++;
		}
		
		DynamicPartitionManager manager = (DynamicPartitionManager) getPartitionManager();
		manager.partition(processors, partitionTasks);
		/*
		 * for(;i<processors.length; i++){ processors[i].setNextTask(null); }
		 */
		return processors;
	}
}
